<?php


namespace app\services;


use think\Exception;
use think\facade\Db;
use think\Request;

class BaseServices
{
	protected const PAGE_SIZE = 6;

	protected Request $request;

	public function __construct (Request $request) {
		$this->request = $request;
	}

	/**
	 * @param array $where (复杂的写闭包)
	 * @param array $fields
	 * @param array $with
	 * @param       $serivces
	 *
	 * @param
	 *
	 * @return mixed
	 * @throws
	 *
	 */
	protected function findOne ($where = [], $fields = ['*'], $with = [], $serivces = '') {
		$query = $this->modelInstance($serivces)->field($fields);
		if (!empty($where)) {
			$query = $query->where($where);
		}

		if (!empty($with)) {
			$query = $query->with($with);
		}

		return $query->find();
	}

	/**
	 * 排序获取全部数据
	 *
	 * @param array  $where
	 * @param array  $fields
	 * @param array  $order
	 * @param array  $with
	 * @param string $serivces
	 *
	 * @param
	 *
	 * @return mixed
	 * @throws
	 *
	 */
	protected function findAll ($where = [], $fields = ['*'], $order = [], $with = [], $serivces = '') {
		$query = $this->modelInstance($serivces)->field($fields);
		if (!empty($where)) {
			$query = $query->where($where);
		}

		if (!empty($with)) {
			$query = $query->with($with);
		}

		if (!empty($order)) {
			$query = $query->order($order);
		}

		return $query->select();
	}

	/**
	 * 分页查询
	 *
	 * @param array  $where
	 * @param string $fields
	 * @param int    $page
	 * @param int    $pagesize
	 * @param array  $order
	 * @param array  $with
	 * @param string $serivces
	 *
	 * @param
	 *
	 * @return mixed
	 * @throws
	 *
	 */
	protected function paginate ($where = [], $fields = '*', $page = 1, $pagesize = self::PAGE_SIZE, $order = ['id' => 'desc'], $with = [], $serivces = '') {
		$query = $this->modelInstance($serivces)->field($fields);
		if (!empty($where)) {
			$query = $query->where($where);
		}

		if (!empty($with)) {
			$query = $query->with($with);
		}

		if (!empty($order)) {
			$query = $query->order($order);
		}

		return $query->limit(($page - 1) * $pagesize, $pagesize)->select();
	}

	/**
	 * 获取记录条数
	 *
	 * @param array  $where
	 * @param string $count
	 * @param string $services
	 *
	 * @param
	 *
	 * @return int
	 * @throws
	 *
	 */
	protected function count ($where = [], $count = 'id', $services = '') {
		$query = $this->modelInstance($services);

		if (!empty($where)) {
			$query = $query->where($where);
		}

		return $query->count($count);
	}

	/**
	 * 模型插入
	 *
	 * @param        $data
	 * @param string $services
	 *
	 * @param
	 *
	 * @return mixed
	 * @throws
	 *
	 */
	protected function saveRecord ($data, $services = '') {
		return $this->modelInstance($services)->save($data);
	}

	/**
	 * 插入一条数据
	 *
	 * @param        $data
	 * @param string $services
	 *
	 * @param
	 *
	 * @return mixed
	 * @throws
	 *
	 */
	protected function insertRecord ($data, $services = '') {
		return Db::name($this->tableInstance($services))->insertGetId($data);
	}

	/**
	 * 批量插入数据
	 *
	 * @param        $data
	 * @param string $services
	 *
	 * @param
	 *
	 * @return int
	 * @throws
	 *
	 */
	protected function batchInsertRecord ($data, $services = '') {
		return Db::name($this->tableInstance($services))->insertAll($data);
	}

	/**
	 * 修改记录，建议先查询出一条记录后再通过模型中的save()方法来修改数据
	 *
	 * @param        $where
	 * @param        $data
	 * @param string $services
	 *
	 * @param
	 *
	 * @return int
	 * @throws
	 *
	 */
	protected function modifyRecord ($where, $data, $services = '') {
		return Db::name($this->tableInstance($services))->where($where)->update($data);
	}

	/**
	 * 通过模型获取数据表名字
	 *
	 * @param string $services
	 *
	 * @param
	 *
	 * @return mixed
	 * @throws
	 *
	 */
	protected function tableInstance (string $services = '') {
		return $this->modelInstance($services)->getTable();
	}

	/**
	 * 获取模型
	 *
	 * @param string $services
	 *
	 * @param
	 *
	 * @return object|\think\App
	 * @throws
	 *
	 */
	protected function model (string $services = '') {
		return $this->modelInstance($services);
	}

	/**
	 * @param string $services
	 *
	 * @return object|\think\App
	 * @throws Exception
	 */
	private function modelInstance (string $services = '') {
		$services = $services ? $services : get_called_class();
		$services = str_replace('\\', '/', $services);
		$index = strrpos($services, '/');
		$key = substr($services, $index + 1);

		if (strtolower(substr($key, -8)) === 'services') {
			$modelName = substr($key, 0, -8);
			$class = 'app\\Model\\' . $modelName;
			$modelFile = str_replace('\\', '/', root_path() . 'app/model/' . $modelName . '.php');
			if (file_exists($modelFile)) {
				return app($class);
			}

			throw new Exception('模型' . $modelName . '不存在');
		}
		throw new Exception('服务' . $key . '不存在');
	}

}